/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package 解析.node.node;

import 解析.node.others.TreeInfo;
import 解析.Matcher;

/**
 *
 * @author yanxi
 */
public class Dollar extends Node {

    public boolean multiline;

    public Dollar(boolean mul) {
        multiline = mul; 
    }
    
    @Override
    public boolean match(Matcher matcher, int i, CharSequence seq) {
        int endIndex = (matcher.anchoringBounds)
                ? matcher.to : matcher.getTextLength();
        if (!multiline) {
            if (i < endIndex - 2) {
                return false;
            }
            if (i == endIndex - 2) {
                char ch = seq.charAt(i);
                if (ch != '\r') {
                    return false;
                }
                ch = seq.charAt(i + 1);
                if (ch != '\n') {
                    return false;
                }
            }
        }
        // Matches before any line terminator; also matches at the
        // end of input
        // Before line terminator:
        // If multiline, we match here no matter what
        // If not multiline, fall through so that the end
        // is marked as hit; this must be a /r/n or a /n
        // at the very end so the end was hit; more input
        // could make this not match here
        if (i < endIndex) {
            char ch = seq.charAt(i);
            if (ch == '\n') {
                // No match between \r\n
                if (i > 0 && seq.charAt(i - 1) == '\r') {
                    return false;
                }
                if (multiline) {
                    return next.match(matcher, i, seq);
                }
            } else if (ch == '\r' || ch == '\u0085'
                    || (ch | 1) == '\u2029') {
                if (multiline) {
                    return next.match(matcher, i, seq);
                }
            } else { // No line terminator, no match
                return false;
            }
        }
        // Matched at current end so hit end
        matcher.hitEnd = true;
        // If a $ matches because of end of input, then more input
        // could cause it to fail!
        matcher.requireEnd = true;
        return next.match(matcher, i, seq);
    }

    @Override
    public boolean study(TreeInfo info) {
        next.study(info);
        return info.deterministic;
    }
    
    public String toString(){
        return "$";
    }
}
